package com.tyc.mb.common.interceptor;

import com.tyc.mb.config.DataSourceContextHolder;
import com.tyc.mb.exception.BaseException;
import com.tyc.mb.model.response.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import com.tyc.mb.common.util.*;

/**
 * 动态配置数据源
 *  如果传入参数没有指定数据源，且注解上也没有指定数据源 则使用默认数据源
 *  在参数和注解都指定的情况下，使用参数中指定的数据源
 *
 * @author tyc
 * @version 1.0
 * @date 2021-11-02 15:36:22
 */
@Aspect
@Component
@Slf4j
@Order(-1)
public class DataSourceAspect {

    @Value("${db.default.sid}")
    private String sid;


    @Pointcut("@annotation(com.tyc.mb.common.interceptor.DataSourceSelector)")
    public void annotationPointcut(){}

    @Around("annotationPointcut()")
    public Object  doAround(ProceedingJoinPoint joinPoint) throws Throwable{
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        DataSourceSelector annotation = method.getAnnotation(DataSourceSelector.class);
        String value = annotation.value();
        if(StringUtils.isEmpty(value)){
            value = sid;
        }
        //获取参数sid的值
        Object sidValue = getValueByParameterName(signature.getParameterNames(), joinPoint.getArgs() ,"sid");
        if(null != sidValue){
            value = String.valueOf(sid);
        }

        DataSourceContextHolder dataSourceContextHolder = (DataSourceContextHolder)ApplicationContextUtil.getBeanByName("dataSourceHolder");
        if(null == dataSourceContextHolder){
            throw new BaseException(ResultCode.SYSTEM_ERROR, "dataSourceContextHolder is null");
        }
        dataSourceContextHolder.setDataSourceKey(Integer.parseInt(value));
        return joinPoint.proceed();
    }

    /**
     * 获取指定方法的某个参数值
     * @param parameterNames 所有参数名
     * @param values 所有参数值
     * @param parameterName 目标参数名
     * @return
     */
    private Object getValueByParameterName(String[] parameterNames, Object[] values, String parameterName) {
        if(parameterNames.length != values.length){
            return null;
        }

        int indexByValue = getIndexByValue(parameterNames, parameterName);
        if(-1 == indexByValue){
            return null;
        }
        return values[indexByValue];
    }

    public int getIndexByValue(String[] arr, String value){
        for (int i = 0; i < arr.length; i++) {
            if(arr[i].equals(value)){
                return i;
            }
        }
        return -1;
    }
}
